%{
    This file is part of StemCellQC, a video bioinformatics software
    toolkit for analysis of phase contrast microscopy videos.
    Copyright 2013-2015 Vincent On. [vincenton001-at-gmail.com]

    StemCellQC is free software: you can redistribute it and/or 
    modify it under the terms of the GNU General Public License as 
    published by the Free Software Foundation, either version 3 of the 
    License, or (at your option) any later version.

    StemCellQC is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with StemCellQC.  If not, see <http://www.gnu.org/licenses/>.
%}

function varargout = Patch_gui(varargin)
% PATCH_GUI MATLAB code for Patch_gui.fig
%      PATCH_GUI, by itself, creates a new PATCH_GUI or raises the existing
%      singleton*.
%
%      H = PATCH_GUI returns the handle to a new PATCH_GUI or the handle to
%      the existing singleton*.
%
%      PATCH_GUI('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in PATCH_GUI.M with the given input arguments.
%
%      PATCH_GUI('Property','Value',...) creates a new PATCH_GUI or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before Patch_gui_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to Patch_gui_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help Patch_gui

% Last Modified by GUIDE v2.5 28-Aug-2014 11:16:22

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @Patch_gui_OpeningFcn, ...
                   'gui_OutputFcn',  @Patch_gui_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT


% --- Executes just before Patch_gui is made visible.
function Patch_gui_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to Patch_gui (see VARARGIN)

% Choose default command line output for Patch_gui
handles.output = hObject;

% Update handles structure
guidata(hObject, handles);

% UIWAIT makes Patch_gui wait for user response (see UIRESUME)
% uiwait(handles.figure1);


% --- Outputs from this function are returned to the command line.
function varargout = Patch_gui_OutputFcn(hObject, eventdata, handles) 
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;


% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


clc
clear all



%% Parameters

save_im = 1;                            %Set to 1 to save images
save_folder_name = 'patched images';    %Name of folder for saved images

save_video = 1; %Set to 1 to save video, must also save images;
framerate = 1;  %framerate of the video

%% load data and labels
% get the directory
folder_name = uigetdir;
pastDir = cd;

dirs = regexp(genpath( folder_name ),'[^;]*','match');
num_dirs = length( dirs );

if save_im == 1
    mkdir( folder_name, save_folder_name );
end

micro_data = [];
index_folders = zeros( num_dirs, 1 );
r = 0;
% patch_im = cell(1);
% im_count = cell(1);
frame_index = cell(1);
Video_list = cell(1);
for i = 1 : num_dirs
    folders = strsplit( dirs{i} , '\');
    switch folders{end}
        %if last folder is labelled 'Ph', load and patch images
        case 'Ph'
%             for j = 1 : length( folders )
%                 well = str2num( folders{ j });
%                 if well ~= 0
%                     index_folders(i,1) = well;
%                     break
%                 end
%             end
            %get video name from folder name
            Video_name = folders{end-2};
            
            %load micro
            if isempty( micro_data )
                micro_folder = strjoin( folders(1:(end-1)), '\' );
                [~,micro,~] = xlsread( [ micro_folder '\' 'micro.csv' ]);
                micro_data = extract_micro( micro );
            end
            
            % the list of files in the directory
            list = dir( dirs{ i });
            
            %             % remove '.' and '..' from list
            %             index = find(list(:,1)=='.');
            %             list(index, : ) = [];
            
            %read images from folder
            count = 1;
            for j=1:length(list(:,1))
                if list(j).name(1) ~= '.'
                    patch(count).image = imread( deblank( [ dirs{ i } '\' list(j,:).name ] ) );
                    count = count + 1;
                end
            end
            
            %get image data
            if r == 0
                [r, c, d] = size( patch( 1 ).image );
                im_type = class( patch( 1 ).image );
            end
            
            OL = str2double(micro_data.Overlap);
            PR = str2double(micro_data.Height);
            PC = str2double(micro_data.Width);
            
            %Find current frame of current video
            new_video = 1;
            if isempty( Video_list{1} )     %Create videolist
                Video_list{1} = Video_name;
                frame_index{1} = 1;
                new_video = 0;
                frame = 1;
                
                if save_im == 1
                    mkdir( [folder_name '\' save_folder_name], Video_name );
                end
                
            else
                for j = 1 : length( Video_list ) %Find video name and increase index
                    if strcmp( Video_list{j}, Video_name )
                        frame_index{j} = frame_index{j} + 1;
                        new_video = 0;
                        frame = frame_index{j};
                        break
                    else
                        
                    end
                end
            end
            
            %Add to video list if name does not exist
            if new_video == 1;
                N_videos = numel(Video_list) + 1;
                Video_list{ N_videos } = Video_name;
                frame_index{ N_videos } = 1;
                frame = 1;
                if save_im == 1
                    mkdir( [folder_name '\' save_folder_name], Video_name );
                end
            end
            
            %initialize patched image
            patch_im = zeros( PR * r - OL*(PR-1), PC * c - OL*(PC-1), d);
            patch_im = typecast2( patch_im, im_type );
            
            %Construct image
            count = 1;
            for j = 1 : PR
                for k = 1 : PC
                    patch_im( c*(j-1)+1-OL*(j-1):c*j-OL*(j-1) , r*(k-1)-OL*(k-1)+1 : r*k-OL*(k-1), : ) = patch(count).image;
                    count = count + 1;
                end
            end
            
            %save image
            if save_im == 1
                im_name = sprintf('%05d',[frame]);
                imwrite( patch_im, [ folder_name '\' save_folder_name '\' Video_name '\' im_name '.tif' ]);
                clear patch_im
            end
%             im_count = im_count + 1;
            clear patch
    end
end

%% Save as video
if save_video == 1
    mkdir( [folder_name '\' save_folder_name], 'Videos' );
    for i = 1 : length( Video_list )
        % the list of files in the directory
        list = dir( [ folder_name '\' save_folder_name '\' Video_list{ i } ]);
        
        %read images from folder
        count = 1;
        patched = cell(1);
        for j=1:length(list(:,1))
            if list(j).name(1) ~= '.'
                patched{count} = imread( deblank( [ folder_name '\' save_folder_name '\' Video_list{ i } '\' list(j,:).name ] ) );
                count = count + 1;
            end
        end
        
        im_var2video( Video_list{ i }, framerate, patched );
        movefile( [pastDir '/' Video_list{ i } '.avi'], [folder_name '\' save_folder_name '\Videos'])
    end
end